package com.tim.helper.inactive.postman;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tim.MainHelper;
import com.tim.helper.analysis.xssd.XssdService2Postman;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * 基于swagger json，构建postman测试对象
 *
 */
public class Swagger2PostMan {
	String swaggerReqUrl = "http://dev-xqxc-boss.dailytalks.cn/v2/api-docs";
	String COOKIE_NAME = "cookie";
	String TOKEN_NAME = "token";
	String TEST_SCRIPT = XssdService2Postman.ReqGenerator.TEST_SCRIPT;
	String HOST_NAME = "host";

	Map<String, String> tagNameMap = new HashMap<>();

	@Test
	public void swagger2Postman() throws IOException {
		JSONObject json = getSwaggerJson(swaggerReqUrl);

		//解析
		JSONObject paths = json.getJSONObject("paths");
		List<JSONObject> list = new ArrayList<>();
		// 按tags分组。path：summary请求描述，tags归属分组
		for(String path : paths.keySet()) {
			JSONObject jObj = paths.getJSONObject(path);
			String reqMethod = jObj.keySet().toArray(new String[0])[0];
			// summary请求描述，设置reqMethod、path
			JSONObject mJson = jObj.getJSONObject(reqMethod);
			mJson.put("reqMethod", reqMethod);// url后缀+Using+请求方法
			mJson.put("path", path);// 请求路径
			mJson.put("tag", mJson.getJSONArray("tags").getString(0));// 归属tag
			list.add(mJson);
		}
		Map<String, List<JSONObject>> mapList = list.stream().collect(Collectors.groupingBy(item->item.getString("tag")));

		JSONArray tags = json.getJSONArray("tags");
		for(Object tag : tags) {
			JSONObject jObj = (JSONObject) tag;
			// name paths中tag，description描述
			tagNameMap.put(jObj.getString("name"), jObj.getString("description"));
		}

		File file = new File(MainHelper.OUTPUT_DIR);
		if(!file.exists()) {
			file.mkdirs();
		}

		//生成postman collection
		for(Entry<String, List<JSONObject>> entry : mapList.entrySet()) {
			String classAlias = entry.getKey();
			String classTag = tagNameMap.get(classAlias);//类描述
			classTag = classTag.replace("/", "").replaceAll("\\s+", "");

			List<JSONObject> mtds = entry.getValue();//方法
			List<Object> result = new ArrayList<>();
			for(JSONObject mtd : mtds) {
				// 参数顺序：reqName, reqPath、COOKIE_NAME、TOKEN_NAME, TEST_SCRIPT, HOST_NAME
				String req = new XssdService2Postman.CommonReqGenerator().getReq(
						mtd.getString("summary"),
						mtd.getString("path").replaceFirst("/", ""),
						COOKIE_NAME, TOKEN_NAME, TEST_SCRIPT, HOST_NAME
						, mtd.getString("reqMethod")
				);
				result.add(req);
			}
			String reqItemContent =
					result.stream().map(Objects::toString).collect(Collectors.joining(","));
			String project = String.format(XssdService2Postman.POSTMAN_COLLECTION_TEMPLATE, classTag, reqItemContent);
			try {
				Files.write(Paths.get(MainHelper.OUTPUT_DIR, classTag+".json"), Collections.singletonList(project));
			} catch (IOException e) {
				e.printStackTrace();
			}
//			System.out.println(jsonStr);

		}
		System.out.println(MainHelper.OUTPUT_DIR);
	}

	private JSONObject getSwaggerJson(String swaggerReqUrl) throws IOException {
		URL url = new URL(swaggerReqUrl);
		Object obj = url.getContent();
		InputStream is = (InputStream) obj;
		//inputstream读byte[]直接转字符串，会乱码
		InputStreamReader reader = new InputStreamReader(is);
		int size = 8*1024;
		char[] chars = new char[size];
		int len = 0;
		StringBuffer buf = new StringBuffer();
		do {
			len = reader.read(chars);
			if(len>0){
				buf.append(new String(chars, 0, len));
			}
		}while(len!=-1);//-1时，为流结束
		JSONObject json = JSON.parseObject(buf.toString());
		return json;
	}

}
